package hu.debrecen.adastra.card.repository.domain;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import org.springframework.data.jpa.domain.AbstractPersistable;

@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type")
@DiscriminatorValue(Account.TYPE)
public class Account extends AbstractPersistable<Long> {

	public static final String TYPE = "HUMAN";

	private static final long serialVersionUID = 1L;

	@Column(unique = true, nullable = false)
	private String username;

	private String firstName;

	private String lastName;

	@Column(name = "type", insertable = false, updatable = false)
	private String type;

	@OneToMany(cascade = { CascadeType.ALL }, orphanRemoval = true, fetch = FetchType.LAZY)
	@JoinColumn(name = "account_fk")
	private final List<Achievement> achievements = new LinkedList<Achievement>();

	@OneToOne(mappedBy = "account", cascade = { CascadeType.ALL }, orphanRemoval = true, fetch = FetchType.LAZY)
	private PlayerStatistics playerStatistics;

	public Account() {
		super();
	}

	public Account(final String username) {
		super();
		this.username = username;
	}

	public Account(final String username, final String firstName, final String lastName) {
		super();
		this.username = username;
		this.firstName = firstName;
		this.lastName = lastName;
		this.playerStatistics = new PlayerStatistics();
		this.playerStatistics.setAccount(this);
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(final String username) {
		this.username = username;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(final String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(final String lastName) {
		this.lastName = lastName;
	}

	public String getType() {
		return this.type;
	}

	public void setType(final String type) {
		this.type = type;
	}

	public List<Achievement> getAchievements() {
		return this.achievements;
	}

	public PlayerStatistics getPlayerStatistics() {
		return this.playerStatistics;
	}

	public void setPlayerStatistics(final PlayerStatistics playerStatistics) {
		this.playerStatistics = playerStatistics;
	}

	@Override
	public String toString() {
		return "Account [" + this.username + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = (prime * result) + ((this.username == null) ? 0 : this.username.hashCode());
		return result;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (!super.equals(obj)) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		Account other = (Account) obj;
		if (this.username == null) {
			if (other.username != null) {
				return false;
			}
		} else if (!this.username.equals(other.username)) {
			return false;
		}
		return true;
	}

}
